<template>
  <div class="EchartsCore" style="width: 100%; height: 100%; position: relative">
    <div ref="container" v-show="!showEmpty" style="width: 100%; height: 100%"></div>
    <div v-if="showEmpty" :style="slotProps.style">
      <slot name="empty"><empty /></slot>
    </div>
    <slot v-else-if="ready" v-bind="slotProps"></slot>
  </div>
</template>
<script>
import { debounce, every, get } from 'lodash-es';
// 引入 echarts 核心模块，核心模块提供了 echarts 使用必须要的接口。
import * as _Echarts from 'echarts/core';
// 引入 Canvas 渲染器，注意引入 CanvasRenderer 或者 SVGRenderer 是必须的一步
import { CanvasRenderer } from 'echarts/renderers';
// 引入柱状图图表，图表后缀都为 Chart
import { PieChart, BarChart, LineChart } from 'echarts/charts';
// 引入提示框，标题组件，组件后缀都为 Component
import { TitleComponent, TooltipComponent, LegendComponent, GridComponent, ToolboxComponent } from 'echarts/components';

import Empty from '../Empty/index.vue';

// 注册必须的组件
_Echarts.use([
  CanvasRenderer,
  TitleComponent,
  TooltipComponent,
  LegendComponent,
  GridComponent,
  ToolboxComponent,
  PieChart,
  BarChart,
  LineChart,
]);

const EchartsCore = {
  name: 'EchartsCore',
  components: { Empty },
  props: {
    components: { type: Array, default: () => [] },
    option: { type: Object, default: () => ({}) },
  },
  data() {
    return {
      ready: false,
      showEmpty: true,
      slotProps: {
        echarts: null,
        style: {
          position: 'absolute',
          top: '50%',
          left: '50%',
          transform: 'translate(-50%,-50%)',
        },
      },
    };
  },
  created() {
    _Echarts.use(this.components);
    this.onWinResize = debounce(() => {
      if (this.echarts) {
        this.echarts.resize();
        this.$emit('resize');
      }
    }, 300);
  },
  mounted() {
    if (window.ResizeObserver) {
      this.resizeObserver = new ResizeObserver(() => {
        this.onWinResize();
      });
      this.resizeObserver.observe(this.$refs.container);
    } else {
      window.addEventListener('resize', this.onWinResize);
    }
    this.$watch(
      () => this.option,
      debounce(() => {
        let series = this.option.series || [];
        series = Array.isArray(series) ? series : [series];
        this.showEmpty = every(series, (item) => {
          return !item || !item.data || !item.data.length;
        });
        if (this.showEmpty) {
          return;
        }
        if (!this.echarts) {
          this.echarts = _Echarts.init(this.$refs.container);
          this.slotProps.echarts = this.echarts;
          this.ready = true;
          this.$emit('ready', { echarts: this.echarts });
        }
        this.renderChart();
      }, 500),
      { immediate: true, deep: true }
    );
  },
  unmounted() {
    window.removeEventListener('resize', this.onWinResize);
    if (this.resizeObserver) {
      this.resizeObserver.disconnect();
    }
    if (this.echarts) {
      this.echarts.dispose();
    }
  },
  methods: {
    renderChart() {
      if (this.echarts && !this.showEmpty) {
        this.$nextTick(() => {
          // 添加点击事件
          this.echarts.on('click', (data) => {
            if (data.componentType == 'xAxis' || data.componentType == 'yAxis') {
              this.$emit('echartsClick', get(data, 'value', {}));
            } else {
              this.$emit('echartsClick', get(data, 'data', {}));
            }
          });
          this.echarts.on('legendselectchanged', (data) => {
            this.$emit('echartsLegendClick', data);
          });
          this.echarts.setOption(this.option);
          this.$emit('rendered', { echarts: this.echarts });
        });
      }
    },
    dispatchAction(opt = {}) {
      if (this.echarts && opt && opt.type) {
        this.echarts.dispatchAction(opt);
      }
    },
    on() {
      if (this.echarts && arguments[0]) {
        this.echarts.on.apply(this.echarts, arguments);
      }
    },
    off() {
      if (this.echarts && arguments[0]) {
        this.echarts.off.apply(this.echarts, arguments);
      }
    },
  },
};
export const Echarts = _Echarts;
export default EchartsCore;
</script>
